package com.app.business.service;

import com.app.business.calculate.CalculateUtils;
import com.app.business.en.Status;
import com.app.business.model.Contract;
import com.app.business.model.OverAreaPriceNew;
import com.app.business.model.Parameter;
import com.app.business.model.ZsProject;
import com.app.business.utils.UserPermissionUtil;
import com.app.system.jpa.JpaBaseDao;
import com.app.system.jpa.PageBean;
import com.app.system.jpa.Wrapper;
import com.app.system.permission.model.UserInfo;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.WebUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.SerializationUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 征收项目管理
 * Created by ddz on 2019/11/14 10:45.
 */
@Service
@Transactional
public class ParameterService extends JpaBaseDao<Parameter, Integer> {

    @Autowired
    private OverAreaPriceNewService overAreaPriceNewService;
    @Autowired
    private ContractService contractService;


    /**
     * 得到参数配置
     *
     * @return
     */
    public List<Parameter> parameterList() {
        //查询语句
        StringBuffer hql = new StringBuffer("from Parameter p order by p.id desc,p.name ");
        Map<String,Object> map = new HashMap<>();
        return this.findHql(hql.toString(),map);
    }

    /**
     * 分页处理
     *
     * @return
     */
    public PageBean<Parameter> getParameterPageBean() {
        //查询语句
        StringBuffer query = new StringBuffer(" p from Parameter p ");

        //默认排序(PageBean指定排序字段类型的话，则默认排序不使用)
        StringBuffer orderBy = new StringBuffer("p.id desc,p.name");
        Wrapper wrapper = new Wrapper(query, orderBy);
        wrapper.initSearchParams();
        return this.pageHql(wrapper);
    }

    /**
     * 征收项目参数配置数据保存
     * @param request
     * @return
     */
    public synchronized Response dataFormSave(HttpServletRequest request){
        int parameterId = ParamUtils.getInt(request, "parameterId", 0);
        Parameter parameter = this.findOne(parameterId);
        if (parameter == null) {
            parameter = new Parameter();
        }
        WebUtils.bind(request, parameter);

        Precondition.checkAjaxArguement(parameter != null,"1111","未找到征收项目，保存失败！");

        this.save(parameter);
        //保存之前先删除数据
        this.overAreaPriceNewService.deleteOverAreaNewPriceByParameterId(parameter.getId());

        String[] minAreaArray = ParamUtils.getStringParameters(request,"minArea");    //最小面积
        String[] maxAreaArray = ParamUtils.getStringParameters(request,"maxArea");    //最大面积
        String[] priceArray = ParamUtils.getStringParameters(request,"price");    //购房单价
        String[] sortNumArray = ParamUtils.getStringParameters(request,"sortNum");    //排序号
        //必须不为空，且长度一致（必填）
        Precondition.checkAjaxArguement(minAreaArray != null && maxAreaArray != null && minAreaArray.length == maxAreaArray.length,"2222","面积区间数据填写不规范！");
        int length = minAreaArray.length;
        String minArea = null,maxArea = null,price = null,sortNum = null;
        for (int i = 0; i < length; i++){
            minArea = null;maxArea = null;price = null;sortNum = null;
            minArea = minAreaArray[i];maxArea = maxAreaArray[i];price = priceArray[i];sortNum = sortNumArray[i];
            if (minArea != null && !minArea.equals("") && maxArea != null && !maxArea.equals("") && price != null && !price.equals("") && sortNum != null && !sortNum.equals("")){
                OverAreaPriceNew overAreaPrice = new OverAreaPriceNew();
                overAreaPrice.setMinArea(BigDecimalUtils.stringToBigDecimal(minArea));   //最小面积
                overAreaPrice.setMaxArea(BigDecimalUtils.stringToBigDecimal(maxArea));   //最大面积
                overAreaPrice.setPrice(BigDecimalUtils.stringToBigDecimal(price));   //补偿单价
                overAreaPrice.setSortNum(Integer.valueOf(sortNum));    //排序号
                overAreaPrice.setParameter(parameter);   //征收项目
                this.overAreaPriceNewService.save(overAreaPrice);
            }
        }
        return new Response("0001", "保存成功!");
    }


    /**
     * 通过配置表id 获取扩购区间关键面积（只针对有两个扩购区间的）
     * @param parameterId
     * @return
     */
    public BigDecimal getOverArea(Integer parameterId) {
        StringBuffer sql = new StringBuffer(" SELECT MIN(o.max_area) FROM over_area_price_new o WHERE o.parameter_id =:parameterId ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("parameterId", parameterId);
        return BigDecimalUtils.stringToBigDecimal(String.valueOf(this.findSqlObject(sql.toString(), map).get(0)));
    }


    /**
     * 新增扩购区间
     * @param request
     * @return
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public synchronized Response setSaveOverArea(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer contractId = ParamUtils.getInt(request, "contractId", 0);
        String overAreaStr = ParamUtils.getString(request, "overArea", "0");
        BigDecimal overArea = BigDecimalUtils.stringToBigDecimal(overAreaStr);//节点面积
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkAjaxArguement(contract != null, "0012", "找不到该户信息！");
        Parameter parameter = this.findOne(contract.getParameter().getId());//本协议对应的配置表
        //若执行此方法需新clone一条数据
        Parameter parameterItem = this.cloneParameter(parameter,contract);
        parameterItem.setId(null);//clone 过来的数据Id要清空，不然会报错
        this.save(parameterItem);
        Precondition.checkAjaxArguement(overArea.compareTo(BigDecimal.ZERO) >= 0, "0012", "此处不可填入小于0的数值！");
        if (overArea.compareTo(BigDecimal.ZERO) == 0) {//若等于0则无节点面积  直接9500
            OverAreaPriceNew overAreaPriceNew = new OverAreaPriceNew();
            //仅需插入1条
            overAreaPriceNew.setParameter(parameterItem);
            overAreaPriceNew.setMinArea(BigDecimal.ZERO);
            overAreaPriceNew.setMaxArea(new BigDecimal("9999"));
            overAreaPriceNew.setPrice(new BigDecimal("9800"));
            overAreaPriceNew.setSortNum(10);
            this.overAreaPriceNewService.save(overAreaPriceNew);
        } else if (overArea.compareTo(BigDecimal.ZERO) > 0) {
            //第1条
            OverAreaPriceNew overAreaPriceNewOne = new OverAreaPriceNew();
            overAreaPriceNewOne.setParameter(parameterItem);
            overAreaPriceNewOne.setMinArea(BigDecimal.ZERO);
            overAreaPriceNewOne.setMaxArea(overArea);
            overAreaPriceNewOne.setPrice(new BigDecimal("3000"));
            overAreaPriceNewOne.setSortNum(10);
            this.overAreaPriceNewService.save(overAreaPriceNewOne);
            //第2条
            OverAreaPriceNew overAreaPriceNewTwo = new OverAreaPriceNew();
            overAreaPriceNewTwo.setParameter(parameterItem);
            overAreaPriceNewTwo.setMinArea(overArea);
            overAreaPriceNewTwo.setMaxArea(new BigDecimal("9999"));
            overAreaPriceNewTwo.setPrice(new BigDecimal("9800"));
            overAreaPriceNewTwo.setSortNum(20);
            this.overAreaPriceNewService.save(overAreaPriceNewTwo);
        }
        //将新配置的表付值到当前协议中
        contract.setParameter(parameterItem);
        this.contractService.save(contract);
        CalculateUtils.main(contract.getId());

        Response response = new Response();
        response.setCode("0001");
        return response;
    }

    /**
     * 使用 Spring BeanUtils（Spring 框架的一部分）
     * @param parameterItem
     * @param contract
     * @return
     */
    public  Parameter cloneParameter(Parameter parameterItem,Contract contract) {
        Parameter parameterSon = new Parameter();
        try {
            BeanUtils.copyProperties(parameterItem,parameterSon);
        } catch (Exception e) {
        }
        parameterSon.setName(new Date() + "_" + contract.getId() + "_" + contract.getContractCode());
        return parameterSon;
    }

}
